package com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.SmsWnsChargeCategory;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.SmsWnsChargeCategoryDetail;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.req.SmsWnsChargeCategoryReq;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.resp.SmsWnsChargeCategoryDetailResp;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.resp.SmsWnsChargeCategoryResp;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsChargeCategoryDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsChargeCategoryMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.SmsWnsChargeCategoryService;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.util.CategoryItemUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.constant.ChargeCategoryConstant.CHARGE_CATEGORY_TYPE_LIST;

/**
 * <p>
 * 收费类别表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-01-15
 */
@Service
public class SmsWnsChargeCategoryServiceImpl extends ServiceImpl<SmsWnsChargeCategoryMapper, SmsWnsChargeCategory> implements SmsWnsChargeCategoryService {
    @Resource
    private SmsWnsChargeCategoryDetailMapper smsWnsChargeCategoryDetailMapper;
    @Resource
    private CategoryItemUtil categoryItemUtil;

    @Override
    @Transactional
    public ResponseResult addCategory(SmsWnsChargeCategoryReq categoryReq) {
        if (isNullOrEmpty(categoryReq.getName(), categoryReq.getType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (!CHARGE_CATEGORY_TYPE_LIST.contains(categoryReq.getType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        // 校验名称是否重复
        List<SmsWnsChargeCategory> sameNameChargeCategoryList = this.list(new LambdaQueryWrapper<SmsWnsChargeCategory>()
                .eq(SmsWnsChargeCategory::getName, categoryReq.getName()));
        if (!sameNameChargeCategoryList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.WNS_CHARGE_CATEGORY_NAME_EXIST);
        }

        // 校验顺序是否冲突
        if (!isNullOrEmpty(categoryReq.getSort())) {
            if (categoryReq.getSort() <= 1) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }

            List<SmsWnsChargeCategory> sameSortChargeCategoryList = this.list(new LambdaQueryWrapper<SmsWnsChargeCategory>()
                    .ge(SmsWnsChargeCategory::getSort, categoryReq.getSort()));
            if (!sameSortChargeCategoryList.isEmpty()) {
                // 大于当前顺序的每个流程 顺序+1
                for (SmsWnsChargeCategory chargeCategory : sameSortChargeCategoryList) {
                    chargeCategory.setSort(chargeCategory.getSort() + 1);
                }
                this.updateBatchById(sameSortChargeCategoryList);
            }
        }

        SmsWnsChargeCategory chargeCategory = new SmsWnsChargeCategory();
        BeanUtils.copyProperties(categoryReq, chargeCategory);
        if (categoryReq.getSort() == null) {
            int count = this.count();
            chargeCategory.setSort(count + 1);
        }
        this.save(chargeCategory);

        return CommonResult.success(chargeCategory.getId());
    }

    @Override
    @Transactional
    public ResponseResult updateCategory(SmsWnsChargeCategoryReq categoryReq) {
        if (isNullOrEmpty(categoryReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsWnsChargeCategory chargeCategory = this.getById(categoryReq.getId());
        if (chargeCategory == null) {
            return CommonResult.failed(CommonCodeEnum.WNS_CHARGE_CATEGORY_NOT_EXIST);
        }

        // 校验是否可修改
        if (!chargeCategory.getIsModified()) {
            return CommonResult.failed(CommonCodeEnum.WNS_CHARGE_CATEGORY_CAN_NOT_UPDATE_OR_DELETE);
        }

        // 校验名称是否重复
        if (!isNullOrEmpty(categoryReq.getName())) {
            List<SmsWnsChargeCategory> sameNameChargeCategoryList = this.list(new LambdaQueryWrapper<SmsWnsChargeCategory>()
                    .eq(SmsWnsChargeCategory::getName, categoryReq.getName())
                    .ne(SmsWnsChargeCategory::getId, categoryReq.getId()));
            if (!sameNameChargeCategoryList.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.WNS_CHARGE_CATEGORY_NAME_EXIST);
            }
        }

        // 校验顺序是否冲突
        if (!isNullOrEmpty(categoryReq.getSort())) {
            if (categoryReq.getSort() <= 1) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }

            List<SmsWnsChargeCategory> sameSortChargeCategoryList = this.list(new LambdaQueryWrapper<SmsWnsChargeCategory>()
                    .eq(SmsWnsChargeCategory::getSort, categoryReq.getSort())
                    .ne(SmsWnsChargeCategory::getId, categoryReq.getId()));
            if (!sameSortChargeCategoryList.isEmpty()) {
                // 顺序进行替换
                SmsWnsChargeCategory conflictCategory = sameSortChargeCategoryList.get(0);
                conflictCategory.setSort(chargeCategory.getSort());
                this.updateById(sameSortChargeCategoryList.get(0));
            }
        }

        // 修改当前流程
        BeanUtils.copyProperties(categoryReq, chargeCategory);
        this.updateById(chargeCategory);

        return CommonResult.success();
    }

    @Override
    public ResponseResult listCategory(Integer pageNum, Integer pageSize, String searchStr) {
        int count = this.count();
        if (count < 2) {
            // 初始化分类数据
            categoryItemUtil.initCategoryData();
        }

        LambdaQueryWrapper<SmsWnsChargeCategory> queryWrapper = new LambdaQueryWrapper<SmsWnsChargeCategory>()
                .orderByAsc(SmsWnsChargeCategory::getSort);

        if (!isNullOrEmpty(searchStr)) {
            StringUtils.deleteWhitespace(searchStr);
            queryWrapper.and(i -> i.like(SmsWnsChargeCategory::getName, searchStr).or()
                    .like(SmsWnsChargeCategory::getDescription, searchStr));
        }

        Page<SmsWnsChargeCategory> page = new Page<>(pageNum, pageSize);
        this.page(page, queryWrapper);
        List<SmsWnsChargeCategoryResp> categoryRespList = page.getRecords().stream().map(category -> {
            SmsWnsChargeCategoryResp categoryResp = new SmsWnsChargeCategoryResp();
            BeanUtils.copyProperties(category, categoryResp);

            List<SmsWnsChargeCategoryDetail> detailList = smsWnsChargeCategoryDetailMapper.selectList(new LambdaQueryWrapper<SmsWnsChargeCategoryDetail>()
                    .eq(SmsWnsChargeCategoryDetail::getCategoryId, category.getId()));
            List<SmsWnsChargeCategoryDetailResp> detailRespList = detailList.stream().map(detail -> {
                SmsWnsChargeCategoryDetailResp detailResp = new SmsWnsChargeCategoryDetailResp();
                BeanUtils.copyProperties(detail, detailResp);
                return detailResp;
            }).collect(Collectors.toList());

            categoryResp.setDetailRespList(detailRespList);
            return categoryResp;
        }).collect(Collectors.toList());

        return CommonResult.success(categoryRespList, (int) page.getTotal());
    }

    @Override
    public ResponseResult categoryDetail(String categoryId) {
        SmsWnsChargeCategory category = this.getById(categoryId);
        if (category == null) {
            return CommonResult.failed(CommonCodeEnum.WNS_CHARGE_CATEGORY_NOT_EXIST);
        }

        SmsWnsChargeCategoryResp categoryResp = new SmsWnsChargeCategoryResp();
        BeanUtils.copyProperties(category, categoryResp);

        List<SmsWnsChargeCategoryDetail> detailList = smsWnsChargeCategoryDetailMapper.selectList(new LambdaQueryWrapper<SmsWnsChargeCategoryDetail>()
                .eq(SmsWnsChargeCategoryDetail::getCategoryId, category.getId()));
        List<SmsWnsChargeCategoryDetailResp> detailRespList = detailList.stream().map(detail -> {
            SmsWnsChargeCategoryDetailResp detailResp = new SmsWnsChargeCategoryDetailResp();
            BeanUtils.copyProperties(detail, detailResp);
            return detailResp;
        }).collect(Collectors.toList());
        categoryResp.setDetailRespList(detailRespList);

        return CommonResult.success(categoryResp);
    }
}
